home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / intrvews / xgrab.lha / xgrab / ui / mymenu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-04-24  |  5.1 KB  |  294 lines

  1. /**
  2.    GRAB Graph Layout and Browser System
  3.  
  4.    Copyright (c) 1987, 1988, 1989 Stanford University
  5.    Copyright (c) 1989, Tera Computer Company
  6.  **/
  7.  
  8.   /**
  9.      Just like menus in the InterViews 2.5 source.
  10.      The biggest difference is they have no memory of what your last 
  11.      selection was, so they pop up at the same place.
  12.  
  13.      Someday we'll have to use the new ones, but for now...
  14.    **/
  15.  
  16. #include "mymenu.h"
  17. #include <InterViews/box.h>
  18. #include <InterViews/font.h>
  19. #include <InterViews/frame.h>
  20. #include <InterViews/painter.h>
  21. #include <InterViews/sensor.h>
  22. #include <InterViews/shape.h>
  23. #include <InterViews/world.h>
  24.  
  25. MyMenu::MyMenu (boolean persist) 
  26. {
  27.     persistent = persist;
  28.     Init();
  29. }
  30.  
  31. MyMenu::MyMenu (const char* name, boolean persist) 
  32. {
  33.     SetInstance(name);
  34.     persistent = persist;
  35.     Init();
  36. }
  37.  
  38. MyMenu::MyMenu (Sensor* in, Painter* out, boolean persist = true) : (in, out) 
  39. {
  40.     persistent = persist;
  41.     Init();
  42. }
  43.  
  44. void MyMenu::Init () 
  45. {
  46.     SetClassName("MyMenu");
  47.     SetCanvasType(CanvasSaveUnder);
  48.     layout = new VBox;
  49.     cur = nil;
  50.     xoff = shape->width / 2;
  51.     yoff = shape->height;
  52.     delete input;
  53.     input = new Sensor(onoffEvents);
  54.     input->Catch(DownEvent);
  55.     input->Catch(UpEvent);
  56. }
  57.  
  58. void MyMenu::Reconfig () 
  59. {
  60.     MonoScene::Reconfig();
  61.  
  62.     if (xoff == 0) 
  63.     {
  64.     xoff = shape->width / 2;
  65.     yoff = shape->height;
  66.     }
  67. }
  68.  
  69. void MyMenu::DoInsert (Interactor* i, boolean, Coord&, Coord&) 
  70. {
  71.     layout->Insert(i);
  72. }
  73.  
  74. void MyMenu::Compose () 
  75. {
  76.     Interactor* i;
  77.     Coord x, y;
  78.  
  79.     i = new ShadowFrame(layout);
  80.     PrepareToInsert(i);
  81.     MonoScene::DoInsert(i, false, x, y);
  82. }
  83.  
  84. /*
  85.  * Pop up a menu in the world at the coordinates specified
  86.  * by the given event.  The event is what caused the popup request --
  87.  * set it to what causes the menu to close.  Store the selected item
  88.  * in the final parameter as well as the current selection.
  89.  */
  90.  
  91. void MyMenu::Popup (register Event& e, Interactor*& item) 
  92. {
  93.     register Interactor* i;
  94.     World* w;
  95.     Coord wx, wy;
  96.  
  97.     e.GetAbsolute(w, wx, wy);
  98.     /* force computation of (xoff, yoff) */
  99.     Config(w);
  100.     xoff = shape->width / 2;
  101.     yoff = shape->height;
  102.     w->InsertPopup(this, wx - xoff, wy - yoff);
  103.     i = nil;
  104.  
  105.     for (;;) 
  106.     {
  107.     Read(e);
  108.  
  109.     if (e.eventType == UpEvent) 
  110.     {
  111.         break;
  112.     }
  113.  
  114.     if (e.target->Parent() == layout) 
  115.     {
  116.         i = e.target;
  117.         i->Handle(e);
  118.  
  119.         if (e.eventType == UpEvent) 
  120.         {
  121.         break;
  122.         }
  123.  
  124.         if (!persistent) 
  125.         {
  126.         Poll(e);
  127.  
  128.         if (e.x < 0 || e.x > xmax || e.y < 0 || e.y > ymax) 
  129.         {
  130.             i = nil;
  131.             break;
  132.         }
  133.         }
  134.     }
  135.     else if (e.target == this && e.eventType == OffEvent) 
  136.     {
  137.         i = nil;
  138.  
  139.         if (!persistent) 
  140.         {
  141.         break;
  142.         }
  143.     }
  144.     }
  145.  
  146.     if (i != nil) 
  147.     {
  148.     xoff = shape->width / 2;
  149.     yoff = shape->height;
  150.     i->GetRelative(xoff, yoff, this);
  151.     }
  152.  
  153.     cur = i;
  154.     item = i;
  155.     e.GetAbsolute(wx, wy);
  156.     e.target = w;
  157.     e.x = wx;
  158.     e.y = wy;
  159.     w->Remove(this);
  160.     Flush();
  161. }
  162.  
  163. void MyMenu::Handle (Event& e) 
  164. {
  165.     for (;;) 
  166.     {
  167.     if (e.eventType == UpEvent) 
  168.     {
  169.         break;
  170.     }
  171.     else if (e.target->Parent() == layout) 
  172.     {
  173.         cur = e.target;
  174.         cur->Handle(e);
  175.  
  176.         if (e.eventType == UpEvent) 
  177.         {
  178.         break;
  179.         }
  180.     }
  181.     else if (e.target != this) 
  182.     {
  183.         Parent()->Handle(e);
  184.     }
  185.     else if (e.eventType != DownEvent) 
  186.     {
  187.         cur = nil;
  188.     }
  189.  
  190.     Read(e);
  191.     }
  192. }
  193.  
  194. MyMenuItem::MyMenuItem (int t) {
  195.     Init(t);
  196. }
  197.  
  198. MyMenuItem::MyMenuItem (const char* name, int t) {
  199.     SetInstance(name);
  200.     Init(t);
  201. }
  202.  
  203. MyMenuItem::MyMenuItem (Painter* out, int t) : (nil, out) {
  204.     Init(t);
  205. }
  206.  
  207. void MyMenuItem::Init (int t) {
  208.     SetClassName("MyMenuItem");
  209.     tag = t;
  210.     normal = nil;
  211.     highlight = nil;
  212.     input = onoffEvents;
  213.     input->Reference();
  214. }
  215.  
  216. void MyMenuItem::Reconfig () {
  217.     if (output == highlight) {
  218.     output = normal;
  219.     }
  220.     delete highlight;
  221.     highlight = new Painter(output);
  222.     highlight->SetColors(output->GetBgColor(), output->GetFgColor());
  223.     normal = output;
  224. }
  225.  
  226. MyMenuItem::~MyMenuItem () {
  227.     output = normal;
  228.     delete highlight;
  229. }
  230.  
  231. void MyMenuItem::Handle (Event& e) {
  232.     switch (e.eventType) {
  233.     case OnEvent:
  234.         Highlight();
  235.         break;
  236.     case OffEvent:
  237.         UnHighlight();
  238.         break;
  239.     default:
  240.         /* shouldn't happen */;
  241.     }
  242. }
  243.  
  244. /*
  245.  * Default highlighting is to redraw the item with the highlight painter
  246.  * as output.
  247.  */
  248.  
  249. void MyMenuItem::Highlight () {
  250.     output = highlight;
  251.     Draw();
  252. }
  253.  
  254. void MyMenuItem::UnHighlight () {
  255.     output = normal;
  256.     Draw();
  257. }
  258.  
  259. /*
  260.  * Simple text menu item.
  261.  */
  262.  
  263. TextItem::TextItem (const char* s, int t) : (t) {
  264.     Init(s);
  265. }
  266.  
  267. TextItem::TextItem (const char* name, const char* s, int t) : (name, t) {
  268.     Init(s);
  269. }
  270.  
  271. TextItem::TextItem (Painter* out, const char* s, int t) : (out, t) {
  272.     Init(s);
  273. }
  274.  
  275. void TextItem::Init (const char* s) {
  276.     SetClassName("TextItem");
  277.     text = s;
  278. }
  279.  
  280. static const int pad = 2;
  281.  
  282. void TextItem::Reconfig () {
  283.     MyMenuItem::Reconfig();
  284.     Font* f = output->GetFont();
  285.     shape->width = f->Width(text) + 2*pad;
  286.     shape->height = f->Height() + 2*pad;
  287.     shape->Rigid(0, hfil, 0, 0);
  288. }
  289.  
  290. void TextItem::Redraw (Coord, Coord, Coord, Coord) {
  291.     output->ClearRect(canvas, 0, 0, xmax, ymax);
  292.     output->Text(canvas, text, (xmax - shape->width) / 2 + pad, pad);
  293. }
  294.